import yaml
import os
import json
import datetime
from datetime import timedelta
from web_data_collector import WebDataCollector
from cve_matcher import CVEMatcher
from anomaly_detector import AnomalyDetector
from config_optimizer import ConfigOptimizer
from report_generator import ReportGenerator
from config_adapter import ConfigAdapter


def print_step(message):
    """打印步骤信息，增强可读性"""
    print(f"\n{'=' * 40}")
    print(f"[{datetime.datetime.now().strftime('%H:%M:%S')}] {message}")
    print(f"{'=' * 40}")


def print_top_items(items, max_count=3, item_name="项目"):
    """通用函数：打印前N个项目，兼容不同数据类型"""
    if not items:
        print(f"  未发现{item_name}")
        return

    # 处理列表类型
    if isinstance(items, list):
        count = min(len(items), max_count)
        print(f"  共发现{len(items)}个{item_name}，显示前{count}个：")
        for i, item in enumerate(items[:max_count], 1):
            if isinstance(item, dict) and 'description' in item:
                print(f"  {i}. {item['description']}")
            else:
                print(f"  {i}. {str(item)[:300]}")  # 限制长度避免输出过长
    # 处理字典类型
    elif isinstance(items, dict):
        count = min(len(items), max_count)
        print(f"  共发现{len(items)}个{item_name}，显示前{count}个：")
        for i, (key, value) in enumerate(list(items.items())[:max_count], 1):
            print(f"  {i}. {key}: {str(value)[:300]}")  # 限制长度
    # 处理其他类型
    else:
        print(f"  发现{item_name}：{str(items)[:300]}")


def main():
    # 读取配置文件 - 使用新的配置适配器
    config_adapter = ConfigAdapter()
    
    # 验证配置
    if not config_adapter.validate_config():
        print("配置验证失败，使用默认配置")
    
    # 获取API配置
    api_key = config_adapter.get_api_key()
    api_url = config_adapter.get_api_url()
    model_name = config_adapter.get_model()
    
    # 保留原有的config.yaml读取用于其他配置（如CVE配置）
    old_config_path = os.path.join(os.path.dirname(__file__), 'config.yaml')
    try:
        with open(old_config_path, 'r', encoding='utf-8') as f:
            old_config = yaml.safe_load(f)
    except FileNotFoundError:
        print("警告: 未找到config.yaml，使用默认配置")
        old_config = {
            'cve': {
                'cache_dir': "../cve_data",
                'db_path': "../cve.db"
            }
        }

    # 步骤1: 收集Web服务器基础信息
    print_step("1. 收集Web服务器基础信息")
    collector = WebDataCollector()
    web_info = collector.collect_web_info()
    print(f"检测到的web信息:")
    print(f"  解析后的版本: {web_info.get('version', '未知')}")
    print(f"  配置路径: {web_info.get('config_path', '未知')}")
    collector.save_to_file()

    # 步骤2: 软件包缺陷检测 (CVE漏洞检测)
    print_step("2. 软件包缺陷检测 (CVE漏洞检测)")
    matcher = CVEMatcher(cache_dir=old_config['cve']['cache_dir'],db_path=old_config['cve']['db_path'])
    # 检查数据库连接状态
    db_status = matcher.check_database_connection()
    print("\nCVE数据库连接状态:")
    print(json.dumps(db_status, indent=2))

    if db_status["status"] != "connected" or db_status["record_count"] == 0:
        print("\n数据库未初始化或为空，正在更新CVE数据库...")
        matcher.update_cve_database(full_update=True)

    # 更新CVE数据库(首次使用需要完整更新)
    if not os.path.exists(matcher.db_path):
        print("首次运行，正在下载完整的CVE数据库...")
        matcher.update_cve_database(full_update=True)
    else:
        # 每周执行一次完整更新
        db_age = datetime.datetime.now() - datetime.datetime.fromtimestamp(os.path.getmtime(matcher.db_path))
        if db_age > timedelta(days=7):
            print("CVE数据库超过7天未更新，正在更新...")
            matcher.update_cve_database(full_update=True)

    # 获取Web版本并检查漏洞
    web_version = matcher.get_software_version("httpd")
    print(f"检测到web版本: {web_version}")

    cve_result = None  # 初始化CVE结果变量
    if web_version == "unknown":
        print("无法自动确定web版本，请尝试以下方法手动检查:")
        print("1. 运行命令: httpd -v 或 web2 -v")
        print("2. 运行命令: rpm -q httpd --queryformat '%{VERSION}'")
        print("3. 检查 /etc/httpd/conf/httpd.conf 文件中的版本信息")

        # 允许手动输入版本号
        manual_version = input("请输入web版本号(如2.4.6，直接回车跳过): ").strip()
        if manual_version:
            cve_result = matcher.get_web_vulnerabilities(manual_version)

    else:
        cve_result = matcher.get_web_vulnerabilities(web_version)

    # 保存报告到文件
    if cve_result:
        report_file = f"web_cve_report_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        with open(report_file, 'w') as f:
            json.dump(cve_result, f, indent=2)
        print(f"报告已保存到 {report_file}")
    else:
        print("未生成CVE报告，跳过保存步骤")

    # 步骤3: 异常模式检测
    print_step("3. 异常模式检测")
    detector = AnomalyDetector()
    anomaly_result = detector.detect_anomalies()
    print(f"异常检测完成，检查日志文件: {len(anomaly_result['log_files_checked'])}个")
    print(f"发现异常: {len(anomaly_result['anomalies'])}个")

    print_top_items(anomaly_result['anomalies'], 3, "异常")

    # 生成异常扫描脚本
    script_path = detector.generate_anomaly_script()
    print(f"异常扫描脚本已生成: {script_path}")

    # 步骤4: 配置优化检测
    print_step("4. 配置优化检测")
    optimizer = ConfigOptimizer()
    print("收集性能指标...")
    optimizer.collect_performance_metrics()

    config_issues = optimizer.evaluate_config()
    print_top_items(config_issues.get('issues', []), 3, "配置问题")

    performance_bottlenecks = optimizer.detect_performance_bottlenecks()
    print_top_items(performance_bottlenecks.get('bottlenecks', []), 3, "性能瓶颈")

    # 步骤5: 生成优化建议报告
    print_step("5. 生成优化建议报告")
    if not api_key:
        print("警告: 未设置API密钥，将使用默认建议生成报告")

    report_generator = ReportGenerator(api_key, api_url, model_name, config_adapter, cve_result)

    report_generator.collect_all_data()
    report_generator.generate_recommendations()
    report_path = report_generator.save_report()
    print(f"优化报告已生成:")
    print(f"  HTML格式: {report_path}")
    print(f"  JSON格式: {report_path.replace('.html', '.json')}")

    print_step("所有检测任务完成")


if __name__ == "__main__":
    main()
